#include "sw_deque.h"

deque* deque_init()
{
    deque* deq = (deque*)malloc(sizeof(deque));
    bzero(deq, sizeof(deque));
    deq->map_size = 8;
    deq->pointer_size = 8;
    deq->map = (map_pointer)malloc(sizeof(pointer) * deq->map_size);
    for (int i = 0; i < deq->map_size; i++) {
        deq->map[i] = (pointer)malloc(sizeof(value_type) * deq->pointer_size);
        printf("deq->map[i] = %p|size[%x]\n", deq->map[i], sizeof(value_type) * deq->pointer_size);
    }

    deq->start.node = &(deq->map[deq->map_size/2]);
    deq->start.cur = nullptr;
    deq->start.first = &((*deq->start.node)[0]);
    deq->start.last = &((*deq->start.node)[deq->pointer_size - 1]);

    deq->finish.node = &(deq->map[deq->map_size/2]);
    deq->finish.cur = nullptr;
    deq->finish.first = &((*deq->finish.node)[0]);
    deq->finish.last = &((*deq->finish.node)[deq->pointer_size - 1]);
}

void deque_destroy(deque* deq)
{
    for (int i = 0; i < deq->map_size; i ++) {
        free(deq->map[i]);
    }
    free(deq);
}

deque_iterator deque_start(deque* deq)
{
    return deq->start;
}

deque_iterator deque_finish(deque* deq)
{
    return deq->finish;
}

void deque_push_front(deque* deq, value_type value)
{
    if (deq->start.cur == nullptr) {/* isempty */
        deq->start.cur = deq->start.first + ((deq->pointer_size - 1) /2);
        deq->finish.cur = deq->start.cur;
    } else if (deq->start.cur > deq->start.first) {
        deq->start.cur--;
    } else if (deq->start.cur == deq->start.first) {
        deq->start.node--;//TODO:map重分配问题
        deq->start.first = &((*deq->start.node)[0]);
        deq->start.last = &((*deq->start.node)[deq->pointer_size - 1]);
        deq->start.cur = deq->start.last;
    }
    *deq->start.cur = value;
    printf("[%p]%d\n", deq->start.cur, value);
}

void deque_push_back(deque* deq, value_type value)
{
    if (deq->finish.cur == nullptr) {/* isempty */
        deq->finish.cur = deq->finish.first + ((deq->pointer_size - 1) /2);
        deq->start.cur = deq->finish.cur;
    } else if (deq->finish.cur < deq->finish.last) {
        deq->finish.cur++;
    } else if (deq->finish.cur == deq->finish.last) {
        deq->finish.node++;//TODO:map重分配问题
        deq->finish.first = &((*deq->finish.node)[0]);
        deq->finish.last = &((*deq->finish.node)[deq->pointer_size - 1]);
        deq->finish.cur = deq->finish.first;
    }
    *deq->finish.cur = value;
    printf("[%p]%d\n", deq->finish.cur, value);
}

void deque_foreach(deque* deq)
{
    deque_iterator it = deque_start(deq);
    while (it.cur != NULL) {
        printf("[%p](%d)\n", it.cur, *it.cur);
        if (it.cur != NULL && it.cur == deq->finish.cur) {
            break;
        }
        if (it.cur < it.last) {
            it.cur++; 
        }
        else if (it.cur == it.last) {
            it.node++;
            it.first = &((*it.node)[0]);
            it.last = &((*it.node)[deq->pointer_size - 1]);
            it.cur = it.first;
        }
    }
}
